package main

import (
	"fmt"
	"log"
	"os"
	"strings"

	"game-simple/internal/infrastructure/config"
	"game-simple/internal/infrastructure/core"
	"game-simple/internal/infrastructure/database"
)

// generateDiffFromModel 从模型和现有表对比生成 ALTER TABLE SQL
func generateDiffFromModel(modelName string, migrationName string) {
	// 确保模型已扫描
	initModels()

	// 检查模型是否存在
	model, ok := modelRegistry[modelName]
	if !ok {
		log.Fatalf("模型 '%s' 未找到\n可用模型: %s", modelName, getAvailableModels())
	}

	// 加载配置
	configPath := "cmd/web/config.yaml"
	if err := config.LoadConfig(configPath); err != nil {
		// 如果配置文件不存在，尝试使用默认路径
		configPath = "cmd/h5/config.yaml"
		if err := config.LoadConfig(configPath); err != nil {
			log.Fatalf("加载配置失败: %v\n请确保配置文件存在", err)
		}
	}

	// 初始化基础设施（需要数据库连接）
	if err := core.Init(); err != nil {
		log.Fatalf("初始化基础设施失败: %v", err)
	}
	defer core.Close()

	db := database.GetDB()
	if db == nil {
		log.Fatal("数据库未初始化")
	}

	// 生成 ALTER TABLE SQL（支持复杂变更：字段重命名、类型转换、外键）
	alterSQL, err := database.GenerateAlterTableSQL(db, model)
	if err != nil {
		if err.Error() == "表结构没有变化" {
			fmt.Println("✅ 表结构没有变化，无需生成迁移文件")
			return
		}
		// 如果表不存在，可能返回 CREATE TABLE，继续处理
		if !strings.Contains(err.Error(), "CREATE TABLE") {
			log.Fatalf("生成 ALTER TABLE SQL 失败: %v", err)
		}
		// 如果返回 CREATE TABLE，说明表不存在，使用 generate 命令更合适
		fmt.Printf("⚠️  表不存在，建议使用 'generate' 命令生成 CREATE TABLE\n")
		alterSQL, _ = database.GenerateCreateTableSQL(db, model)
	}

	// 检查是否需要多步骤迁移（在 ALTER TABLE 之前执行）
	// 包括类型转换和 NULL -> NOT NULL 的数据迁移
	multiSteps, err := database.GenerateComplexMigrationSteps(db, model)
	if err == nil && len(multiSteps) > 0 {
		fmt.Printf("⚠️  检测到复杂变更，生成多步骤迁移\n")
		// 将多步骤 SQL 添加到迁移文件开头（在 ALTER TABLE 之前执行）
		preSQL := "-- 复杂变更预处理（需要先执行数据迁移）\n" +
			strings.Join(multiSteps, "\n\n") +
			"\n\n-- 结构变更\n"
		alterSQL = preSQL + alterSQL
	}

	// 生成回滚 SQL（简单版本：反向操作）
	dropSQL, _ := database.GenerateDropTableSQL(db, model)

	// 如果没有指定迁移名称，从模型名生成
	if migrationName == "" {
		migrationName = generateDiffMigrationName(modelName)
	}

	// 创建迁移文件
	migrationsDir := "internal/infrastructure/database/migrations"
	version := getNextVersion(migrationsDir)
	filename := fmt.Sprintf("%s/%s_%s.sql", migrationsDir, version, migrationName)

	// 构建迁移文件内容
	content := fmt.Sprintf(`-- UP
-- 自动生成自模型: %s（对比现有表结构）
%s

-- DOWN
-- 注意：回滚 SQL 需要手动编写，因为无法自动生成完整的反向操作
-- 如果添加了字段，应该删除：
-- ALTER TABLE <table_name> DROP COLUMN <column_name>;
-- 如果删除了字段，应该恢复（需要手动添加字段定义）：
-- ALTER TABLE <table_name> ADD COLUMN <column_def>;
%s
`, modelName, alterSQL, dropSQL)

	if err := os.WriteFile(filename, []byte(content), 0644); err != nil {
		log.Fatalf("创建迁移文件失败: %v", err)
	}

	fmt.Printf("✅ 成功生成迁移文件: %s\n", filename)
	fmt.Printf("📝 模型: %s\n", modelName)
	fmt.Printf("📄 迁移名称: %s\n", migrationName)
	fmt.Printf("⚠️  注意：请检查生成的 SQL，特别是回滚部分可能需要手动完善\n")
}

// generateDiffMigrationName 从模型名生成迁移名称
func generateDiffMigrationName(modelName string) string {
	// 移除 Model 后缀
	name := strings.TrimSuffix(modelName, "Model")
	// 转换为 snake_case
	name = toSnakeCase(name)
	return fmt.Sprintf("alter_%s_table", strings.ToLower(name))
}
